/*
 * Copyright (C) 2011 Alex Kuiper
 * 
 * This file is part of PageTurner
 *
 * PageTurner is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * PageTurner is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with PageTurner.  If not, see <http://www.gnu.org/licenses/>.*
 */

package net.nightwhistler.pageturner.activity;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.PowerManager;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.ActionMode;
import android.view.ContextMenu;
import android.view.Display;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SearchView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewSwitcher;

import com.google.inject.Inject;
import com.hzdracom.epubreader.activity.ReadingEpubActivity;
import com.hzdracom.epubreader.consts.EpubConst;
import com.hzdracom.epubreader.db.BookInfoDbAdapter;
import com.hzdracom.epubreader.entity.BookInfoItem;
import com.hzdracom.epubreader.util.CSSHelp;
import com.hzdracom.epubreader.util.FileUtil;
import com.hzdracom.epubreader.views.BrightControlView;
import com.hzdracom.epubreader.views.FontSettingsView;
import com.hzdracom.epubreader.views.FontSettingsView.FontSettingsListener;
import com.hzdracom.epubreader.views.ReadingBg;
import com.hzdracom.epubreader.views.ReadingBg.ReadingBgListener;
import com.shwread.android.qysw10000243.R;

import net.nightwhistler.pageturner.Configuration;
import net.nightwhistler.pageturner.Configuration.AnimationStyle;
import net.nightwhistler.pageturner.Configuration.ColourProfile;
import net.nightwhistler.pageturner.Configuration.ReadingDirection;
import net.nightwhistler.pageturner.Configuration.ScrollStyle;
import net.nightwhistler.pageturner.TextUtil;
import net.nightwhistler.pageturner.activity.DialogFactory.SearchCallBack;
import net.nightwhistler.pageturner.animation.Animations;
import net.nightwhistler.pageturner.animation.Animator;
import net.nightwhistler.pageturner.animation.PageCurlAnimator;
import net.nightwhistler.pageturner.bookmark.Bookmark;
import net.nightwhistler.pageturner.bookmark.BookmarkDatabaseHelper;
import net.nightwhistler.pageturner.dto.HighLight;
import net.nightwhistler.pageturner.dto.SearchResult;
import net.nightwhistler.pageturner.dto.TocEntry;
import net.nightwhistler.pageturner.tasks.SearchTextTask;
import net.nightwhistler.pageturner.view.AnimatedImageView;
import net.nightwhistler.pageturner.view.HighlightManager;
import net.nightwhistler.pageturner.view.NavGestureDetector;
import net.nightwhistler.pageturner.view.NavigationCallback;
import net.nightwhistler.pageturner.view.SearchResultAdapter;
import net.nightwhistler.pageturner.view.bookview.BookView;
import net.nightwhistler.pageturner.view.bookview.BookViewListener;
import net.nightwhistler.pageturner.view.bookview.CoverChapterView;
import net.nightwhistler.pageturner.view.bookview.TextLoader;
import net.nightwhistler.pageturner.view.bookview.TextSelectionCallback;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import logic.bean.BookBean;
import logic.constants.Const;
import logic.dao.BookDao;
import logic.db.DBHelper;
import nl.siegmann.epublib.domain.Author;
import nl.siegmann.epublib.domain.Book;
import nl.siegmann.epublib.domain.Metadata;
import nl.siegmann.epublib.domain.Resource;
import nl.siegmann.epublib.epub.EpubReader;
import roboguice.fragment.RoboFragment;
import roboguice.inject.InjectView;

@SuppressLint("NewApi")
public class ReadingFragment extends RoboFragment implements BookViewListener, TextSelectionCallback, SearchCallBack,
		FontSettingsListener {

	private static final String POS_KEY = "offset:";
	private static final String IDX_KEY = "index:";

	protected static final int REQUEST_CODE_GET_CONTENT = 2;

	private static final Logger LOG = LoggerFactory.getLogger("ReadingFragment");

	private long bookId;

	@Inject
	private Configuration config;

	@Inject
	private DialogFactory dialogFactory;

	@Inject
	private Context context;

	@InjectView(R.id.mainContainer)
	private ViewSwitcher viewSwitcher;

	@InjectView(R.id.bookView)
	private BookView bookView;

	@InjectView(R.id.myTitleBarTextView)
	private TextView titleBar;

	@InjectView(R.id.myTitleBarLayout)
	private RelativeLayout titleBarLayout;

	@InjectView(R.id.titleProgress)
	private SeekBar progressBar;

	@InjectView(R.id.percentageField)
	private TextView percentageField;

	@InjectView(R.id.authorField)
	private TextView authorField;

	@InjectView(R.id.dummyView)
	private AnimatedImageView dummyView;

	@InjectView(R.id.pageNumberView)
	private TextView pageNumberView;

	@InjectView(R.id.txtCurrTime)
	private TextView txtCurrTime;

	@InjectView(R.id.imgPhonePower)
	private ImageView imgPhonePower;

	@InjectView(R.id.txtChapterName)
	private TextView txtChapterName;

	@InjectView(R.id.layoutBottomToolbar)
	private LinearLayout bottomToolbar;

	@InjectView(R.id.layoutTopToolbar)
	private LinearLayout topToolbar;

	@InjectView(R.id.layoutLeftBar)
	private RelativeLayout layoutLeftBar;

	@InjectView(R.id.viewFontSetting)
	private FontSettingsView fontSettingView;

	@InjectView(R.id.imgFontSettings)
	private ImageButton imgFontSetting;

	@InjectView(R.id.imgDayNightTheme)
	private ImageButton imgDayNightTheme;

	@InjectView(R.id.imgAddBookmark)
	private ImageButton imgAddBookmark;

	@InjectView(R.id.imgBackgroundColor)
	private ImageButton imgBackgroundColor;
	
	@InjectView(R.id.imgBrightness)
	private ImageButton imgBrightness;

	@InjectView(R.id.coverChapterView)
	private CoverChapterView coverChapterView;

	@InjectView(R.id.layoutPlayAudio)
	private LinearLayout layoutPlayAudio;

	@InjectView(R.id.imgAudioControl)
	private ImageButton imgAudioControl;

	@InjectView(R.id.btnNextChapter)
	private ImageButton layoutNextChatper;

	@InjectView(R.id.btnPreChapter)
	private ImageButton layoutPreChapter;

	@Inject
	private TelephonyManager telephonyManager;

	@Inject
	private PowerManager powerManager;

	@Inject
	private TextLoader textLoader;

	@Inject
	private HighlightManager highlightManager;

	@Inject
	private BookmarkDatabaseHelper bookmarkDatabaseHelper;

	private MenuItem searchMenuItem;

	private List<SearchResult> searchResults = new ArrayList<SearchResult>();

	private ProgressDialog waitDialog;

	private String bookTitle;
	private String titleBase;

	private String fileName;
	private int progressPercentage;

	private String language = "en";

	private int currentPageNumber = -1;
	private int totalPageNumber = -1;

	private boolean useCssStyleChanged = false;

	private static enum Orientation {
		HORIZONTAL, VERTICAL
	}

	private static class SavedConfigState {
		private boolean brightness;
		private boolean stripWhiteSpace;
		private String fontName;
		private String serifFontName;
		private String sansSerifFontName;
		private int vMargin;
		private int hMargin;
		private int textSize;
		private boolean scrolling;
		private boolean allowStyling;
		private boolean allowColoursFromCSS;
		private int lineSpaceing;
		
//		private int backgroundColor;
	}

	private SavedConfigState savedConfigState = new SavedConfigState();
	private BookView.SelectedWord selectedWord = null;

	private Handler uiHandler;
	private Handler backgroundHandler;

	private Toast brightnessToast;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// Restore preferences
		this.uiHandler = new Handler();
		HandlerThread bgThread = new HandlerThread("background");
		bgThread.start();
		this.backgroundHandler = new Handler(bgThread.getLooper());

		getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
		
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		return inflater.inflate(R.layout.epub3_fragment_reading, container, false);
	}

	@Override
	public void onViewCreated(View view, Bundle savedInstanceState) {
		super.onViewCreated(view, savedInstanceState);
		setHasOptionsMenu(true);
		activity = getActivity();
		this.bookView.init();
		this.bookView.setCoverChapterView(coverChapterView);
//		this.bookView.setBackgroundColor(config.getBackgroundColor());

		this.progressBar.setFocusable(true);
		this.progressBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

			private int seekValue;

			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
				bookView.navigateToPage(this.seekValue);

			}

			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {
			}

			@Override
			public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
				if (fromUser) {
					LOG.info("seekbar_seekto:" + progress);
					seekValue = progress;
					percentageField.setText(progress + "% ");
				}
			}
		});

		this.bookView.addListener(this);
		this.bookView.setTextSelectionCallback(this);

		initToolbarEvents();

		IntentFilter filterPower = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
		this.getActivity().registerReceiver(powerReceiver, filterPower);

		IntentFilter filterTimeTick = new IntentFilter(Intent.ACTION_TIME_TICK);
		this.getActivity().registerReceiver(timeReceiver, filterTimeTick);

		displayTime();

		// 添加设置的相关Listener
		fontSettingView.setListener(this);
		
		getBookmarks();
		getTableOfContents();
	}

	private int bgColor = -1;
	private ReadingBg bg;
	private void initToolbarEvents() {
		// 工具栏按钮事件响应
		this.imgFontSetting.setOnClickListener(new android.view.View.OnClickListener() {

			@Override
			public void onClick(View arg0) {

				if (fontSettingView.getVisibility() == View.VISIBLE) {
					fontSettingView.setVisibility(View.GONE);
				} else {
					fontSettingView.setVisibility(View.VISIBLE);
				}
			}
		});

		if (config.getColourProfile() == ColourProfile.DAY) {
			imgDayNightTheme.setImageResource(R.drawable.epub3_theme_night_icon);
		} else {
			imgDayNightTheme.setImageResource(R.drawable.epub3_theme_sun_icon);
		}

		restoreColorProfile();

		imgDayNightTheme.setOnClickListener(new android.view.View.OnClickListener() {

			@Override
			public void onClick(View v) {
				if (config.getColourProfile() == ColourProfile.DAY) {
					config.setColourProfile(ColourProfile.NIGHT);
					imgDayNightTheme.setImageResource(R.drawable.epub3_theme_sun_icon);
				} else {
					config.setColourProfile(ColourProfile.DAY);
					imgDayNightTheme.setImageResource(R.drawable.epub3_theme_night_icon);
				}
				updateFromPrefs();
			}
		});

		imgAddBookmark.setOnClickListener(new android.view.View.OnClickListener() {

			@Override
			public void onClick(View v) {
				addCurruentPositonToBookmark();
			}
		});

		bg = (ReadingBg)ReadingBg.getInstance(activity);
		bg.setListener(new ReadingBgListener() {
			@Override
			public void setBg(int color) {
				config.setBackgroundColor(color);
//				bgColor = color;
				bookView.setBackgroundColor(color);
			}
		});
		imgBackgroundColor.setOnClickListener(new android.view.View.OnClickListener() {

			@Override
			public void onClick(View v) {
				//TODO 背景颜色设置
				bg.show(bottomToolbar);
			}
		});
		
		imgBrightness.setOnClickListener(new android.view.View.OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				BrightControlView.getInstance(activity).show(bottomToolbar);
			}
		});

		imgAudioControl.setOnClickListener(new android.view.View.OnClickListener() {

			@Override
			public void onClick(View v) {
				if (bookView.isAudioPlaying()) {
					bookView.pauseAudio();
				} else {
					bookView.startAudio();
				}
			}
		});

		layoutLeftBar.setOnClickListener(new android.view.View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// 打开抽屉
				ReadingEpubActivity.instance.openNavigationDrawer();
			}
		});

		android.view.View.OnClickListener chapterlistener = new android.view.View.OnClickListener() {

			@Override
			public void onClick(View v) {
				if (v.getId() == R.id.btnNextChapter) {
					// 下一章
					bookView.turnNextChapter();
				} else {
					// 上一章
					bookView.turnPrevChapter();
				}

			}
		};

		layoutNextChatper.setOnClickListener(chapterlistener);
		layoutPreChapter.setOnClickListener(chapterlistener);

	}

	private FragmentActivity activity;
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);

		DisplayMetrics metrics = new DisplayMetrics();

		activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);

		displayPageNumber(-1, -1); // Initializes the pagenumber view properly

		// 设置touch动作
		final GestureDetector gestureDetector = new GestureDetector(context, new NavGestureDetector(bookView, this,
				metrics));

		View.OnTouchListener gestureListener = new View.OnTouchListener() {
			public boolean onTouch(View v, MotionEvent event) {

				return gestureDetector.onTouchEvent(event);
			}
		};

		this.viewSwitcher.setOnTouchListener(gestureListener);
		this.bookView.setOnTouchListener(gestureListener);
		this.dummyView.setOnTouchListener(gestureListener);
		
		adapter = new BookInfoDbAdapter(activity,DBHelper.getInstance(activity));

		// 注册菜单
		registerForContextMenu(bookView);
		// 保存阅读配置
		saveConfigState();

		// 获取epub文件信息
		Intent intent = activity.getIntent();
		String file = null;

		if (intent.getData() != null) {
			file = intent.getData().getPath();
		}

		if (intent.getExtras() != null && intent.getExtras().containsKey("BookID")) {
			bookId = intent.getExtras().getLong("BookID");
			this.bookView.setBookId(bookId);
		} else {
			file = null;
		}

		if (file != null && bookId > 0) {
			
//			parseCSS();

			// 根据阅读配置对View和Activity进行配置
			updateFromPrefs();

			// 读取epub文件的相关信息，文件路径，阅读进度等
			updateFileName(savedInstanceState, file);

			// 清除界面并重新载入文字
			bookView.restore();
		}
		
		adapter.open();
		bookItem = adapter.getBookItem(bookId,Const.phone_number);
		adapter.close();
		if(null == bookItem){
			importEpubFile(file);
		}

	}
	private BookInfoDbAdapter adapter;
	private BookInfoItem bookItem;

	private void parseCSS(){
		final String savePath = EpubConst.EPUB_CSS_LOCAL_PATH+bookId+"/"+EpubConst.EPUB_CSS_NAME;
		new Thread(new Runnable()
		{
			@Override
			public void run() {
				CSSHelp.unZipCSS(bookId);
				CSSHelp.parse(context, savePath);
			}
		}).start();
	}
	/**
	 * 保存上一次的配置信息
	 */
	private void saveConfigState() {
		// Cache old settings to check if we'll need a restart later
		savedConfigState.brightness = config.isBrightnessControlEnabled();
		savedConfigState.stripWhiteSpace = config.isStripWhiteSpaceEnabled();

		savedConfigState.hMargin = config.getHorizontalMargin();
		savedConfigState.vMargin = config.getVerticalMargin();

		savedConfigState.textSize = config.getTextSize();
		savedConfigState.fontName = config.getDefaultFontFamily().getName();
		savedConfigState.serifFontName = config.getSerifFontFamily().getName();
		savedConfigState.sansSerifFontName = config.getSansSerifFontFamily().getName();

		savedConfigState.scrolling = config.isScrollingEnabled();
		savedConfigState.allowStyling = config.isAllowStyling();
		savedConfigState.allowColoursFromCSS = config.isUseColoursFromCSS();
		savedConfigState.lineSpaceing = config.getLineSpacing();
		
//		savedConfigState.backgroundColor = config.getBackgroundColor();
	}

	/*
	 * @see roboguice.activity.RoboActivity#onPause()
	 */
	@Override
	public void onPause() {
		LOG.debug("onPause() called.");

		// 保存进度位置信息
		saveReadingPosition();

		super.onPause();
	}

	BroadcastReceiver powerReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {

			// 获取当前电量
			int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);

			// 获取总电量
			int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);

			int currValue = level * 10 / scale;
			String imgResName = "ppw_" + (currValue == 10 ? 10 : currValue + 1);
			imgPhonePower.setImageResource(getResouceID("drawable", imgResName));
		}
	};

	BroadcastReceiver timeReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			// 更新当前时间
			displayTime();
		}
	};

	private void printScreenAndCallState(String calledFrom) {
		boolean isScreenOn = powerManager.isScreenOn();

		if (!isScreenOn) {
			LOG.debug(calledFrom + ": Screen is off");
		} else {
			LOG.debug(calledFrom + ": Screen is on");
		}

		int phoneState = telephonyManager.getCallState();

		if (phoneState == TelephonyManager.CALL_STATE_RINGING || phoneState == TelephonyManager.CALL_STATE_OFFHOOK) {
			LOG.debug(calledFrom + ": Detected call activity");
		} else {
			LOG.debug(calledFrom + ": No active call.");
		}
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		this.closeWaitDialog();
		this.getActivity().unregisterReceiver(powerReceiver);
		this.getActivity().unregisterReceiver(timeReceiver);
	}

	/**
	 * 更新epub文件及进度信息
	 * 
	 * @param savedInstanceState
	 * @param fileName
	 */
	private void updateFileName(Bundle savedInstanceState, String fileName) {

		this.fileName = fileName;

		int lastPos = config.getLastPosition(fileName);
		int lastIndex = config.getLastIndex(fileName);

		if (savedInstanceState != null) {
			lastPos = savedInstanceState.getInt(POS_KEY, lastPos);
			lastIndex = savedInstanceState.getInt(IDX_KEY, lastIndex);
		}

		this.bookView.setFileName(fileName);
		this.bookView.setPosition(lastPos);
		this.bookView.setIndex(lastIndex);

		config.setLastOpenedFile(fileName);
	}

	@Override
	public void chapterUpdate(int index, String ChapterName) {
		txtChapterName.setTextColor(config.getTextColor());
		txtChapterName.setTypeface(config.getDefaultFontFamily().getDefaultTypeface());
		txtChapterName.setText(ChapterName);
		txtChapterName.invalidate();
	}

	@Override
	public void progressUpdate(int progressPercentage, int pageNumber, int totalPages) {

		if (!isAdded() || getActivity() == null) {
			return;
		}

		this.currentPageNumber = pageNumber;

		// Work-around for calculation errors and weird values.
//		if (progressPercentage < 0 || progressPercentage > 100) {
//			return;
//		}

		this.progressPercentage = progressPercentage;

		if (pageNumber > 0) {
			percentageField.setText("" + progressPercentage + "%  " + pageNumber + " / " + totalPages);
			displayPageNumber(pageNumber, totalPages);

		} else {
			percentageField.setText("" + progressPercentage + "%");
		}
	}

	/**
	 * 显示页码
	 * 
	 * @param pageNumber
	 */
	private void displayPageNumber(int pageNumber, int totalNum) {
		String pageString = "";

		if (!config.isScrollingEnabled() && pageNumber > 0) {
			pageString = Integer.toString(pageNumber) + "/" + totalNum;
		}

		if (pageNumber < 0) {
			pageString = "";
			this.progressBar.setEnabled(false);
		} else {
			this.progressBar.setEnabled(true);
			this.progressBar.setProgress(pageNumber);
			this.progressBar.setMax(totalNum);
		}

		currentPageNumber = pageNumber;
		totalPageNumber = totalNum;

		pageNumberView.setTextColor(config.getTextColor());
		pageNumberView.setTypeface(config.getDefaultFontFamily().getDefaultTypeface());
		pageNumberView.setText(pageString);
		pageNumberView.invalidate();

	}

	/**
	 * 更新时间和电量显示
	 */
	private void displayTime() {

		txtCurrTime.setTextColor(config.getTextColor());
		txtCurrTime.setTypeface(config.getDefaultFontFamily().getDefaultTypeface());

		// 更新当前时间
		SimpleDateFormat df = new SimpleDateFormat("HH:mm");// 设置日期格式
		this.txtCurrTime.setText(df.format(new Date()));
		txtCurrTime.invalidate();
	}

	private int getResouceID(String type, String id) {
		return this.getActivity().getResources().getIdentifier(id, type, this.getActivity().getPackageName());
	}

	/**
	 * 更新相关配置
	 */
	private void updateFromPrefs() {

		FragmentActivity activity = getActivity();

		if (activity == null) {
			return;
		}

//		bookView.setBackgroundColor(config.getBackgroundColor());
		bookView.setTextSize(config.getTextSize());

		int marginH = config.getHorizontalMargin();
		int marginV = config.getVerticalMargin();

		this.textLoader.setFontFamily(config.getDefaultFontFamily());
		this.bookView.setFontFamily(config.getDefaultFontFamily());
		this.textLoader.setSansSerifFontFamily(config.getSansSerifFontFamily());
		this.textLoader.setSerifFontFamily(config.getSerifFontFamily());

		bookView.setHorizontalMargin(marginH);
		bookView.setVerticalMargin(marginV);

		if (!isAnimating()) {
			bookView.setEnableScrolling(config.isScrollingEnabled());
		}

		textLoader.setStripWhiteSpace(config.isStripWhiteSpaceEnabled());
		textLoader.setAllowStyling(config.isAllowStyling());
		textLoader.setUseColoursFromCSS(config.isUseColoursFromCSS());

		bookView.setLineSpacing(config.getLineSpacing());

		if (config.isKeepScreenOn()) {
			activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
		} else {
			activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
		}

		restoreColorProfile();
		displayTime();

		if (config.isUseColoursFromCSS() != savedConfigState.allowColoursFromCSS) {
			useCssStyleChanged = true;
			bookView.invalidateCachedText();
		}
		// Check if we need a restart
		if (config.isStripWhiteSpaceEnabled() != savedConfigState.stripWhiteSpace
				|| !config.getDefaultFontFamily().getName().equalsIgnoreCase(savedConfigState.fontName)
				|| !config.getSerifFontFamily().getName().equalsIgnoreCase(savedConfigState.serifFontName)
				|| !config.getSansSerifFontFamily().getName().equalsIgnoreCase(savedConfigState.sansSerifFontName)
				|| config.getHorizontalMargin() != savedConfigState.hMargin
				|| config.getVerticalMargin() != savedConfigState.vMargin
				|| config.getTextSize() != savedConfigState.textSize
				|| config.isScrollingEnabled() != savedConfigState.scrolling
				|| config.isAllowStyling() != savedConfigState.allowStyling
				|| config.getLineSpacing() != savedConfigState.lineSpaceing ) {
			refreshTextUI(true);
			// restartActivity();
		} else if (config.isBrightnessControlEnabled() != savedConfigState.brightness
				|| config.isUseColoursFromCSS() != savedConfigState.allowColoursFromCSS) {
			// 如果只是UI元素修改，只需要重新载入文字
			refreshTextUI(false);
		}
		Configuration.OrientationLock orientation = config.getScreenOrientation();

		switch (orientation) {
		case PORTRAIT:
			getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
			break;
		case LANDSCAPE:
			getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
			break;
		case REVERSE_LANDSCAPE:
			getActivity().setRequestedOrientation(8); // Android 2.3+ value
			break;
		case REVERSE_PORTRAIT:
			getActivity().setRequestedOrientation(9); // Android 2.3+ value
			break;
		default:
			getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
		}
	}

	@Override
	public void onLowMemory() {
		this.textLoader.clearCachedText();
		Toast.makeText(getActivity(), "内存不足，正在进行恢复", Toast.LENGTH_SHORT).show();
		restartActivity();
	}

	/**
	 * 重启Activity 当某些参数更改后需要调用
	 */
	private void restartActivity() {

		onStop();

		// Clear any cached text.
		textLoader.closeCurrentBook();
		Intent intent = new Intent(context, ReadingEpubActivity.class);
		intent.setData(Uri.parse(this.fileName));
		startActivity(intent);

		Activity activity = getActivity();

		if (activity != null) {
			activity.finish();
		}
	}

	private void refreshTextUI(boolean isNeedClearPageOffsets) {
		// 保存进度位置信息
		saveReadingPosition();

		// 保存阅读配置
		saveConfigState();
		this.bookView.setPosition(config.getLastPosition(fileName));
		if (isNeedClearPageOffsets) {
			displayPageNumber(-1, -1);
			bookView.clearPageOffsets();
		}
		bookView.restore();
	}

	public void onWindowFocusChanged(boolean hasFocus) {
		if (hasFocus) {
			hideTitleBar();
			updateFromPrefs();
		} else {
			getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
		}
	}

	public boolean onTouchEvent(MotionEvent event) {
		return bookView.onTouchEvent(event);
	}

	@Override
	public void bookOpened(final Book book) {

		FragmentActivity activity = getActivity();

		if (activity == null) {
			return;
		}

		this.language = this.bookView.getBook().getMetadata().getLanguage();
		LOG.debug("Got language for book: " + language);

		this.bookTitle = book.getTitle();

		this.config.setLastReadTitle(this.bookTitle);

		this.titleBase = this.bookTitle;
		activity.setTitle(titleBase);
		this.titleBar.setText(titleBase);

		activity.supportInvalidateOptionsMenu();

		if (book.getMetadata() != null && !book.getMetadata().getAuthors().isEmpty()) {
			Author author = book.getMetadata().getAuthors().get(0);
			this.authorField.setText(author.getFirstname() + " " + author.getLastname());
		}

		updateFromPrefs();
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {

		// This is a hack to give the longclick handler time
		// to find the word the user long clicked on.

		if (this.selectedWord != null) {

			final CharSequence word = this.selectedWord.getText();
			final int startIndex = this.selectedWord.getStartOffset();
			final int endIndex = this.selectedWord.getEndOffset();

			String header = String.format(getString(R.string.word_select), selectedWord.getText());

			menu.setHeaderTitle(header);

			menu.add(R.string.highlight).setOnMenuItemClickListener(new OnMenuItemClickListener() {
				@Override
				public boolean onMenuItemClick(android.view.MenuItem menuItem) {

					highLight(startIndex, endIndex, word.toString());

					return false;
				}
			});

			this.selectedWord = null;
		}
	}

	@Override
	public void highLight(int from, int to, String selectedText) {

		int pageStart = bookView.getStartOfCurrentPage();

		String text = TextUtil.shortenText(selectedText);

		this.highlightManager.registerHighlight(fileName, text, bookView.getIndex(), pageStart + from, pageStart + to);

		bookView.update();
	}

	private void showHighlightEditDialog(final HighLight highLight) {
		final AlertDialog.Builder editalert = new AlertDialog.Builder(context);

		editalert.setTitle(R.string.text_note);
		final EditText input = new EditText(context);
		LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
				LinearLayout.LayoutParams.WRAP_CONTENT);
		input.setLayoutParams(lp);
		editalert.setView(input);
		input.setText(highLight.getTextNote());

		editalert.setPositiveButton(R.string.save_note, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				highLight.setTextNote(input.getText().toString());
				bookView.update();
				highlightManager.saveHighLights();
			}
		});
		editalert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {

			}
		});

		editalert.setNeutralButton(R.string.clear_note, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				highLight.setTextNote(null);
				bookView.update();
				highlightManager.saveHighLights();
			}
		});

		editalert.show();
	}

	public void onBookmarkClick(final Bookmark bookmark) {

		// Action bar操作方式，暂时不用，改用对话框方式
		// getActivity().startActionMode(new ActionMode.Callback() {
		//
		// private MenuItem delete;
		//
		// @Override
		// public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
		//
		// this.delete = menu.add(R.string.delete);
		// this.delete.setIcon(R.drawable.trash_can);
		//
		// return true;
		// }
		//
		// @Override
		// public boolean onPrepareActionMode(ActionMode actionMode, Menu menu)
		// {
		// actionMode.setTitle(R.string.bookmark_options);
		// return true;
		// }
		//
		// @Override
		// public boolean onActionItemClicked(ActionMode actionMode,
		// MenuItem menuItem) {
		//
		// boolean result = false;
		//
		// if (menuItem == delete) {
		// bookmarkDatabaseHelper.deleteBookmark(bookmark);
		// Toast.makeText(context, R.string.bookmark_deleted,
		// Toast.LENGTH_SHORT).show();
		// result = true;
		// }
		//
		// if (result) {
		// actionMode.finish();
		// }
		//
		// return result;
		// }
		//
		// @Override
		// public void onDestroyActionMode(ActionMode actionMode) {
		//
		// }
		// });

		Dialog dialog = new AlertDialog.Builder(getActivity()).setTitle("确定删除该书签吗？")
				.setPositiveButton("删除", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int whichButton) {
						bookmarkDatabaseHelper.deleteBookmark(bookmark);
						Toast.makeText(context, R.string.bookmark_deleted, Toast.LENGTH_SHORT).show();
						ReadingEpubActivity.instance.initDrawerItems();
					}
				}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int whichButton) {

					}
				}).create();
		dialog.show();
	}

	@Override
	public void onHighLightClick(final HighLight highLight) {

		LOG.debug("onHighLightClick");

		getActivity().startActionMode(new ActionMode.Callback() {

			private MenuItem edit;
			private MenuItem delete;

			// private MenuItem colour;

			@Override
			public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {

				this.edit = menu.add(R.string.edit);
				this.edit.setIcon(R.drawable.epub3_edit);

				// this.colour = menu.add(R.string.set_colour);
				// this.colour.setIcon(R.drawable.color);

				this.delete = menu.add(R.string.delete);
				this.delete.setIcon(R.drawable.epub3_trash_can);

				return true;
			}

			@Override
			public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
				actionMode.setTitle(R.string.highlight_options);
				return true;
			}

			@Override
			public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {

				boolean result = false;

				if (menuItem == edit) {
					showHighlightEditDialog(highLight);
					result = true;
				} else if (menuItem == delete) {
					deleteHightlight(highLight);
					result = true;
				}
				// else if (menuItem == colour) {
				// result = true;
				// }

				if (result) {
					actionMode.finish();
				}

				return result;
			}

			@Override
			public void onDestroyActionMode(ActionMode actionMode) {

			}
		});

	}

	private void deleteHightlight(final HighLight highLight) {

		final OnClickListener deleteHighlight = new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialogInterface, int i) {
				highlightManager.removeHighLight(highLight);
				Toast.makeText(context, R.string.highlight_deleted, Toast.LENGTH_SHORT).show();
				bookView.update();
			}
		};

		if (highLight.getTextNote() != null && highLight.getTextNote().length() > 0) {
			new AlertDialog.Builder(context).setMessage(R.string.notes_attached)
					.setNegativeButton(android.R.string.no, null)
					.setPositiveButton(android.R.string.yes, deleteHighlight).show();
		} else {
			highlightManager.removeHighLight(highLight);
			Toast.makeText(context, R.string.highlight_deleted, Toast.LENGTH_SHORT).show();
			bookView.update();
		}
	}

	private void restoreColorProfile() {
		this.viewSwitcher.setBackgroundColor(config.getBackgroundColor());

		this.bookView.setTextColor(config.getTextColor());
		this.bookView.setLinkColor(config.getLinkColor());

		this.txtChapterName.setTextColor(config.getTextColor());
		this.txtCurrTime.setTextColor(config.getTextColor());
		this.pageNumberView.setTextColor(config.getTextColor());

		if (config.isBrightnessControlEnabled()) {
			int brightness = config.getBrightNess();
			setScreenBrightnessLevel(brightness);
		}
	}

	private void setScreenBrightnessLevel(int level) {

		Activity activity = getActivity();

		if (activity != null) {
			WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
			lp.screenBrightness = (float) level / 100f;
			activity.getWindow().setAttributes(lp);
		}
	}

	@Override
	public void errorOnBookOpening(String errorMessage) {

		LOG.error(errorMessage);

		closeWaitDialog();

		// ReadingActivity readingActivity = (ReadingActivity) getActivity();

		// if ( readingActivity != null ) {

		// NotificationCompat.Builder builder = new
		// NotificationCompat.Builder(readingActivity);
		// builder.setContentTitle(getString(R.string.app_name))
		// .setContentText(errorMessage)
		// .setSmallIcon(R.drawable.cross)
		// .setAutoCancel( true );
		//
		// builder.setTicker(errorMessage);
		// PendingIntent pendingIntent = PendingIntent.getActivity(
		// readingActivity, 0, new Intent(), 0);
		// builder.setContentIntent( pendingIntent );
		//
		// notificationManager.notify( errorMessage.hashCode(), builder.build()
		// );

		// readingActivity.launchActivity(LibraryActivity.class);
		// }
	}

	private ProgressDialog getWaitDialog() {

		if (this.waitDialog == null) {
			this.waitDialog = new ProgressDialog(context);
			waitDialog.setCancelable(false);
			this.waitDialog.setOwnerActivity(getActivity());
		}

		this.waitDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
			@Override
			public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
				// This just consumes all key events and does nothing.
				return true;

			}
		});

		return this.waitDialog;
	}

	private void closeWaitDialog() {

		if (waitDialog != null) {
			this.waitDialog.dismiss();
			this.waitDialog = null;
		}

	}

	@Override
	public void parseEntryComplete(String name) {

		if (name != null && !name.equals(this.bookTitle)) {
			this.titleBase = this.bookTitle + " - " + name;
		} else {
			this.titleBase = this.bookTitle;
		}

		Activity activity = getActivity();

		if (activity != null) {

			activity.setTitle(this.titleBase);

			closeWaitDialog();
		}

	}

	@Override
	public void parseEntryStart(int entry) {

		if (!isAdded() || getActivity() == null || isTextConfigChanged()) {
			return;
		}

		this.viewSwitcher.clearAnimation();
		this.viewSwitcher.setBackgroundDrawable(null);
		restoreColorProfile();
		displayPageNumber(-1, -1); // Clear page number

		ProgressDialog progressDialog = getWaitDialog();
		progressDialog.setMessage(getString(R.string.loading_wait));

		progressDialog.show();
	}

	@Override
	public void readingFile() {
		if (isAdded()) {
			this.getWaitDialog().setMessage(getString(R.string.opening_file));
			if (!getWaitDialog().isShowing()) {
				getWaitDialog().show();
			}
		}
	}

	@Override
	public void renderingText() {
		if (isAdded()) {
			this.getWaitDialog().setMessage(getString(R.string.loading_text));
			// if (!getWaitDialog().isShowing()) {
			// getWaitDialog().show();
			// }
		}
	}

	private boolean isTextConfigChanged() {
		if (useCssStyleChanged) {
			useCssStyleChanged = false;
			return true;
		}
		return false;
	}

	@TargetApi(Build.VERSION_CODES.FROYO)
	private boolean handleVolumeButtonEvent(KeyEvent event) {

		// Disable volume button handling during TTS
		if (!config.isVolumeKeyNavEnabled() || bookView.isAudioPlaying()) {
			return false;
		}

		Activity activity = getActivity();

		if (activity == null) {
			return false;
		}

		boolean invert = false;

		int rotation = Surface.ROTATION_0;

		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
			Display display = activity.getWindowManager().getDefaultDisplay();
			rotation = display.getRotation();
		}

		switch (rotation) {
		case Surface.ROTATION_0:
		case Surface.ROTATION_90:
			invert = false;
			break;
		case Surface.ROTATION_180:
		case Surface.ROTATION_270:
			invert = true;
			break;
		}

		if (event.getAction() != KeyEvent.ACTION_DOWN) {
			return true;
		}

		if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP) {
			if (invert) {
				pageDown(Orientation.HORIZONTAL);
			} else {
				pageUp(Orientation.HORIZONTAL);
			}
		} else if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN) {
			if (invert) {
				pageUp(Orientation.HORIZONTAL);
			} else {
				pageDown(Orientation.HORIZONTAL);
			}
		}

		return true;
	}

	public boolean dispatchKeyEvent(KeyEvent event) {

		int action = event.getAction();
		int keyCode = event.getKeyCode();

		LOG.debug("Got key event: " + keyCode + " with action " + action);

		if (searchMenuItem != null && searchMenuItem.isActionViewExpanded()) {
			boolean result = searchMenuItem.getActionView().dispatchKeyEvent(event);

			if (result) {
				return true;
			}
		}

		final int KEYCODE_NOOK_TOUCH_BUTTON_LEFT_TOP = 92;
		final int KEYCODE_NOOK_TOUCH_BUTTON_LEFT_BOTTOM = 93;
		final int KEYCODE_NOOK_TOUCH_BUTTON_RIGHT_TOP = 94;
		final int KEYCODE_NOOK_TOUCH_BUTTON_RIGHT_BOTTOM = 95;

		boolean nook_touch_up_press = false;

		if (isAnimating() && action == KeyEvent.ACTION_DOWN) {
			stopAnimating();
			return true;
		}

		LOG.debug("Key event is NOT a media key event.");

		switch (keyCode) {

		case KeyEvent.KEYCODE_VOLUME_DOWN:
		case KeyEvent.KEYCODE_VOLUME_UP:
			return handleVolumeButtonEvent(event);

		case KeyEvent.KEYCODE_DPAD_RIGHT:
			if (action == KeyEvent.ACTION_DOWN) {
				pageDown(Orientation.HORIZONTAL);
			}

			return true;

		case KeyEvent.KEYCODE_DPAD_LEFT:
			if (action == KeyEvent.ACTION_DOWN) {
				pageUp(Orientation.HORIZONTAL);
			}

			return true;

		case KeyEvent.KEYCODE_BACK:
			if (action == KeyEvent.ACTION_DOWN) {

				if (isToolbarShowed()) {
					hideToolbar();
					return true;
				}

				// old code 隐藏工具条，处理上一次阅读位置
				// if (titleBarLayout.getVisibility() == View.VISIBLE) {
				// hideTitleBar();
				// updateFromPrefs();
				// return true;
				// } else if (bookView.hasPrevPosition()) {
				// bookView.goBackInHistory();
				// return true;
				// }
			}

			return false;

		case KEYCODE_NOOK_TOUCH_BUTTON_LEFT_TOP:
		case KEYCODE_NOOK_TOUCH_BUTTON_RIGHT_TOP:
			nook_touch_up_press = true;
		case KEYCODE_NOOK_TOUCH_BUTTON_LEFT_BOTTOM:
		case KEYCODE_NOOK_TOUCH_BUTTON_RIGHT_BOTTOM:
			if (!Configuration.IS_NOOK_TOUCH || action == KeyEvent.ACTION_UP)
				return false;
			if (nook_touch_up_press == config.isNookUpButtonForward())
				pageDown(Orientation.HORIZONTAL);
			else
				pageUp(Orientation.HORIZONTAL);
			return true;
		}

		LOG.debug("Not handling key event: returning false.");
		return false;
	}

	private boolean isToolbarShowed() {
		return topToolbar.getVisibility() == View.VISIBLE;
	}

	public void hideToolbar() {
		topToolbar.setVisibility(View.GONE);
		bottomToolbar.setVisibility(View.GONE);
		layoutLeftBar.setVisibility(View.GONE);
		fontSettingView.setVisibility(View.GONE);
		ReadingEpubActivity.instance.setDrawerUseable(false);
	}

	private void showToolbar() {
		topToolbar.setVisibility(View.VISIBLE);
		bottomToolbar.setVisibility(View.VISIBLE);
		layoutLeftBar.setVisibility(View.VISIBLE);
		ReadingEpubActivity.instance.setDrawerUseable(true);
		if (bookView.isAudioPlaying()) {
			layoutPlayAudio.setVisibility(View.VISIBLE);
		} else {
			layoutPlayAudio.setVisibility(View.GONE);
		}
	}

	private boolean isAnimating() {
		Animator anim = dummyView.getAnimator();
		return anim != null && !anim.isFinished();
	}

	private void startAutoScroll() {

		if (viewSwitcher.getCurrentView() == this.dummyView) {
			viewSwitcher.showNext();
		}

		this.viewSwitcher.setInAnimation(null);
		this.viewSwitcher.setOutAnimation(null);

		bookView.setKeepScreenOn(true);

		ScrollStyle style = config.getAutoScrollStyle();

		if (style == ScrollStyle.ROLLING_BLIND) {
			prepareRollingBlind();
		} else {
			preparePageTimer();
		}

		viewSwitcher.showNext();

		uiHandler.post(new AutoScrollRunnable());
	}

	private void prepareRollingBlind() {/*
										 * 
										 * Bitmap before =
										 * getBookViewSnapshot();
										 * 
										 * bookView.pageDown(); Bitmap after =
										 * getBookViewSnapshot();
										 * 
										 * RollingBlindAnimator anim = new
										 * RollingBlindAnimator();
										 * anim.setAnimationSpeed
										 * (config.getScrollSpeed());
										 * 
										 * anim.setBackgroundBitmap(before);
										 * anim.setForegroundBitmap(after);
										 * 
										 * dummyView.setAnimator(anim);
										 */
	}

	private void preparePageTimer() {/*
									 * bookView.pageDown(); Bitmap after =
									 * getBookViewSnapshot();
									 * 
									 * PageTimer timer = new PageTimer(after,
									 * pageNumberView.getHeight());
									 * 
									 * timer.setSpeed(config.getScrollSpeed());
									 * 
									 * dummyView.setAnimator(timer);
									 */
	}

	private void doPageCurl(boolean flipRight, boolean pageDown) {

		if (isAnimating() || bookView == null) {
			return;
		}

		this.viewSwitcher.setInAnimation(null);
		this.viewSwitcher.setOutAnimation(null);

		if (viewSwitcher.getCurrentView() == this.dummyView) {
			viewSwitcher.showNext();
		}

		Bitmap before = getBookViewSnapshot();

		// this.pageNumberView.setVisibility(View.GONE);

		PageCurlAnimator animator = new PageCurlAnimator(flipRight);

		// Pagecurls should only take a few frames. When the screen gets
		// bigger, so do the frames.
		animator.SetCurlSpeed(bookView.getWidth() / 8);

		animator.setBackgroundColor(config.getBackgroundColor());

		if (pageDown) {
			bookView.pageDown();
		} else {
			bookView.pageUp();
		}

		Bitmap after = getBookViewSnapshot();

		if (flipRight) {
			animator.setBackgroundBitmap(after);
			animator.setForegroundBitmap(before);
		} else {
			animator.setBackgroundBitmap(before);
			animator.setForegroundBitmap(after);
		}

		dummyView.setAnimator(animator);

		this.viewSwitcher.showNext();

		uiHandler.post(new PageCurlRunnable(animator));

		dummyView.invalidate();

	}

	private class PageCurlRunnable implements Runnable {

		private PageCurlAnimator animator;

		public PageCurlRunnable(PageCurlAnimator animator) {
			this.animator = animator;
		}

		@Override
		public void run() {

			if (this.animator.isFinished()) {

				if (viewSwitcher.getCurrentView() == dummyView) {
					viewSwitcher.showNext();
				}

				dummyView.setAnimator(null);
				// pageNumberView.setVisibility(View.VISIBLE);

			} else {
				this.animator.advanceOneFrame();
				dummyView.invalidate();

				int delay = 1000 / this.animator.getAnimationSpeed();

				uiHandler.postDelayed(this, delay);
			}
		}
	}

	private class AutoScrollRunnable implements Runnable {
		@Override
		public void run() {

			if (dummyView.getAnimator() == null) {
				LOG.debug("BookView no longer has an animator. Aborting rolling blind.");
				stopAnimating();
			} else {

				Animator anim = dummyView.getAnimator();

				if (anim.isFinished()) {
					startAutoScroll();
				} else {
					anim.advanceOneFrame();
					dummyView.invalidate();

					uiHandler.postDelayed(this, anim.getAnimationSpeed() * 2);
				}
			}
		}
	}

	private void stopAnimating() {

		if (dummyView.getAnimator() != null) {
			dummyView.getAnimator().stop();
			this.dummyView.setAnimator(null);
		}

		if (viewSwitcher.getCurrentView() == this.dummyView) {
			viewSwitcher.showNext();
		}

		// this.pageNumberView.setVisibility(View.VISIBLE);
		bookView.setKeepScreenOn(false);
	}

	private Bitmap getBookViewSnapshot() {

		try {
			Bitmap bitmap = Bitmap.createBitmap(viewSwitcher.getWidth(), viewSwitcher.getHeight(), Config.ARGB_8888);
			Canvas canvas = new Canvas(bitmap);

			bookView.layout(0, 0, viewSwitcher.getWidth(), viewSwitcher.getHeight());

			bookView.draw(canvas);

			// if (config.isShowPageNumbers()) {
			//
			// /**
			// * FIXME: creating an intermediate bitmap here because I can't
			// * figure out how to draw the pageNumberView directly on the
			// * canvas and have it show up in the right place.
			// */
			//
			// Bitmap pageNumberBitmap = Bitmap.createBitmap(
			// pageNumberView.getWidth(), pageNumberView.getHeight(),
			// Config.ARGB_8888);
			// Canvas pageNumberCanvas = new Canvas(pageNumberBitmap);
			//
			// pageNumberView.layout(0, 0, pageNumberView.getWidth(),
			// pageNumberView.getHeight());
			// pageNumberView.draw(pageNumberCanvas);
			//
			// canvas.drawBitmap(pageNumberBitmap, 0, viewSwitcher.getHeight()
			// - pageNumberView.getHeight(), new Paint());
			//
			// pageNumberBitmap.recycle();
			//
			// }

			// 封面页
			if (this.coverChapterView.getVisibility() == View.VISIBLE) {
				Bitmap bitmapCover = Bitmap.createBitmap(viewSwitcher.getWidth(), viewSwitcher.getHeight(),
						Config.ARGB_8888);
				Canvas coverCanvas = new Canvas(bitmapCover);
				coverChapterView.layout(0, 0, viewSwitcher.getWidth(), viewSwitcher.getHeight());
				coverChapterView.draw(coverCanvas);
				canvas.drawBitmap(bitmapCover, 0, 0, new Paint());

				bitmapCover.recycle();
			}

			return bitmap;
		} catch (OutOfMemoryError out) {
			viewSwitcher.setBackgroundColor(config.getBackgroundColor());
		}

		return null;
	}

	private void prepareSlide(Animation inAnim, Animation outAnim) {

		Bitmap bitmap = getBookViewSnapshot();
		dummyView.setImageBitmap(bitmap);

		// this.pageNumberView.setVisibility(View.GONE);

		inAnim.setAnimationListener(new Animation.AnimationListener() {

			public void onAnimationStart(Animation animation) {
			}

			public void onAnimationRepeat(Animation animation) {
			}

			@Override
			public void onAnimationEnd(Animation animation) {
				onSlideFinished();
			}
		});

		viewSwitcher.layout(0, 0, viewSwitcher.getWidth(), viewSwitcher.getHeight());
		dummyView.layout(0, 0, viewSwitcher.getWidth(), viewSwitcher.getHeight());

		this.viewSwitcher.showNext();

		this.viewSwitcher.setInAnimation(inAnim);
		this.viewSwitcher.setOutAnimation(outAnim);
	}

	private void onSlideFinished() {
		// if (currentPageNumber > 0) {
		// // this.pageNumberView.setVisibility(View.VISIBLE);
		// }
	}

	private void pageDown(Orientation o) {

		if (isToolbarShowed()) {
			hideToolbar();
			return;
		}

		if (bookView.isAtEnd()) {
			Toast.makeText(getActivity(), "已经阅读到最后一页", Toast.LENGTH_SHORT).show();
			return;
		}

		stopAnimating();

		if (o == Orientation.HORIZONTAL) {

			AnimationStyle animH = config.getHorizontalAnim();
			ReadingDirection direction = config.getReadingDirection();

			if (animH == AnimationStyle.CURL) {
				doPageCurl(direction == ReadingDirection.LEFT_TO_RIGHT, true);
			} else if (animH == AnimationStyle.SLIDE) {

				if (direction == ReadingDirection.LEFT_TO_RIGHT) {
					prepareSlide(Animations.inFromRightAnimation(), Animations.outToLeftAnimation());
				} else {
					prepareSlide(Animations.inFromLeftAnimation(), Animations.outToRightAnimation());
				}

				viewSwitcher.showNext();
				bookView.pageDown();
			} else {
				bookView.pageDown();
			}

		} else {
			if (config.getVerticalAnim() == AnimationStyle.SLIDE) {
				prepareSlide(Animations.inFromBottomAnimation(), Animations.outToTopAnimation());
				viewSwitcher.showNext();
			}

			bookView.pageDown();
		}

	}

	private void pageUp(Orientation o) {
		if (isToolbarShowed()) {
			hideToolbar();
			return;
		}

		if (bookView.isAtStart()) {
			Toast.makeText(getActivity(), "当前是第一页", Toast.LENGTH_SHORT).show();
			return;
		}

		stopAnimating();

		if (o == Orientation.HORIZONTAL) {

			AnimationStyle animH = config.getHorizontalAnim();
			ReadingDirection direction = config.getReadingDirection();

			if (animH == AnimationStyle.CURL) {
				doPageCurl(direction == ReadingDirection.RIGHT_TO_LEFT, false);
			} else if (animH == AnimationStyle.SLIDE) {
				if (direction == ReadingDirection.LEFT_TO_RIGHT) {
					prepareSlide(Animations.inFromLeftAnimation(), Animations.outToRightAnimation());
				} else {
					prepareSlide(Animations.inFromRightAnimation(), Animations.outToLeftAnimation());
				}
				viewSwitcher.showNext();
				bookView.pageUp();
			} else {
				bookView.pageUp();
			}

		} else {

			if (config.getVerticalAnim() == AnimationStyle.SLIDE) {
				prepareSlide(Animations.inFromTopAnimation(), Animations.outToBottomAnimation());
				viewSwitcher.showNext();
			}

			bookView.pageUp();
		}
	}

	@Override
	public void onPrepareOptionsMenu(Menu menu) {

		// FragmentActivity activity = getActivity();
		//
		// if (activity == null) {
		// return;
		// }
		//
		// MenuItem nightMode = menu.findItem(R.id.profile_night);
		// MenuItem dayMode = menu.findItem(R.id.profile_day);
		//
		// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
		// // activity.getActionBar().show();
		// }
		//
		// if (config.getColourProfile() == ColourProfile.DAY) {
		// dayMode.setVisible(false);
		// nightMode.setVisible(true);
		// } else {
		// dayMode.setVisible(true);
		// nightMode.setVisible(false);
		// }
		//
		// // Only show open file item if we have a file manager installed
		// Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
		// intent.setType("file/*");
		// intent.addCategory(Intent.CATEGORY_OPENABLE);
		//
		// if (!isIntentAvailable(context, intent)) {
		// menu.findItem(R.id.open_file).setVisible(false);
		// }

		// activity.getWindow().addFlags(
		// WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
		// activity.getWindow().clearFlags(
		// WindowManager.LayoutParams.FLAG_FULLSCREEN);
	}

	private void hideTitleBar() {
		titleBarLayout.setVisibility(View.GONE);
	}

	/**
	 * This is called after the file manager finished.
	 */
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);

		if (resultCode == Activity.RESULT_OK && data != null) {
			// obtain the filename
			Uri fileUri = data.getData();
			if (fileUri != null) {
				String filePath = fileUri.getPath();
				if (filePath != null) {
					loadNewBook(filePath);
				}
			}
		}
	}

	private void loadNewBook(String fileName) {

		Activity activity = getActivity();

		if (activity != null) {

			activity.setTitle(R.string.app_name);
			this.bookTitle = null;
			this.titleBase = null;

			bookView.clear();
			bookView.releaseResources();

			updateFileName(null, fileName);

			bookView.restore();
		}
	}

	@Override
	public void onStop() {
		super.onStop();

		LOG.debug("onStop() called.");
		printScreenAndCallState("onStop()");

		closeWaitDialog();
	}

	public BookView getBookView() {
		return this.bookView;
	}

	public void saveReadingPosition() {
		if (this.bookView != null) {

			int index = this.bookView.getIndex();
			int position = this.bookView.getProgressPosition();

			if (index != -1 && position != -1) {
				config.setLastPosition(this.fileName, position);
				config.setLastIndex(this.fileName, index);
			}
//			if(config.getColourProfile() != ColourProfile.NIGHT && bgColor != -1){
//				config.setBackgroundColor(bgColor);
//			}
			
			BookBean bean = new BookBean(bookId, bookTitle, Const.phone_number, String.valueOf(System.currentTimeMillis()));
			BookDao.getInstance(activity).updateReadTime(bean);

			// 获取数据库记录
			BookInfoDbAdapter db = new BookInfoDbAdapter(getActivity(),DBHelper.getInstance(getActivity()));
			db.open();
			BookInfoItem item = db.getBookItem(bookId,Const.phone_number);
			if (item != null) {
				// 保存阅读进度
				item.setLastChapterId(index + "");
				item.setLastCharIndex(position);
				item.setLastReadTime(new Date());
				if (totalPageNumber > 0 && currentPageNumber >= 0) {
					item.setReadPercent(currentPageNumber / (float) totalPageNumber);
				}
			}
			db.updateTask(bookId, item);
			db.close();
		}

	}

	public void share(int from, int to, String selectedText) {

		int pageStart = bookView.getStartOfCurrentPage();

		String text = bookTitle + ", " + authorField.getText() + "\n";

		int offset = pageStart + from;

		int pageNumber = bookView.getPageNumberFor(bookView.getIndex(), offset);
		int totalPages = bookView.getTotalNumberOfPages();

		if (pageNumber != -1) {
			text = text + String.format(getString(R.string.page_number_of), pageNumber, totalPages) + " ("
					+ progressPercentage + "%)\n\n";

		} else {
			text += "" + progressPercentage + "%\n\n";
		}

		text += selectedText;

		Intent sendIntent = new Intent();
		sendIntent.setAction(Intent.ACTION_SEND);

		sendIntent.putExtra(Intent.EXTRA_TEXT, text);
		sendIntent.setType("text/plain");

		startActivity(Intent.createChooser(sendIntent, getText(R.string.abs__share_action_provider_share_with)));

	}

	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		inflater.inflate(R.menu.epub3_reading_menu, menu);

		this.searchMenuItem = menu.findItem(R.id.search_text);

		if (this.searchMenuItem != null) {
			final SearchView searchView = (SearchView) searchMenuItem.getActionView();

			if (searchView != null) {

				searchView.setSubmitButtonEnabled(true);
				searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {

					// This is a work-around, since we get the
					// onQuerySubmit() event twice
					// when the user hits enter
					private String lastQuery = "";

					@Override
					public boolean onQueryTextSubmit(String query) {

						if (query.equals(lastQuery) && searchResults != null) {
							showSearchResultDialog(searchResults);
						} else if (!query.equals(lastQuery)) {
							searchResults = null;
							lastQuery = query;
							performSearch(query);
						}

						return true;
					}

					@Override
					public boolean onQueryTextChange(String newText) {
						return false;
					}
				});
			}
		}
	}

	@Override
	public void onOptionsMenuClosed(android.view.Menu menu) {
		updateFromPrefs();
		hideTitleBar();
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		hideTitleBar();

		// Handle item selection
		switch (item.getItemId()) {

		// case R.id.profile_night:
		// config.setColourProfile(ColourProfile.NIGHT);
		// this.restartActivity();
		// return true;
		//
		// case R.id.profile_day:
		// config.setColourProfile(ColourProfile.DAY);
		// this.restartActivity();
		// return true;

		case R.id.search_text:
			onSearchRequested();
			return true;

		case R.id.preferences:
			openSetting();
			return true;

			// case R.id.open_file:
			// launchFileManager();
			// return true;

			// case R.id.add_bookmark:
			// addCurruentPositonToBookmark();
			// return true;

		default:
			return super.onOptionsItemSelected(item);
		}
	}

	private void addCurruentPositonToBookmark() {
		FragmentTransaction ft = getFragmentManager().beginTransaction();
		ft.addToBackStack(null);
		AddBookmarkFragment fragment = new AddBookmarkFragment();

		fragment.setFilename(this.fileName);
		fragment.setBookmarkDatabaseHelper(bookmarkDatabaseHelper);
		fragment.setBookIndex(this.bookView.getIndex());
		fragment.setBookPosition(this.bookView.getProgressPosition());

		String firstLine = this.bookView.getFirstLine();
		firstLine = firstLine.replace(BookView.COMPLEX_OBJ_STRING_HOLDER, "");

		if (firstLine.length() > 20) {
			firstLine = firstLine.substring(0, 20) + "…";
		}

		fragment.setInitialText(firstLine);
		fragment.show(ft, "dialog");
	}

	public void openSetting() {
		saveConfigState();
		Intent i = new Intent(context, PageTurnerPrefsActivity.class);
		startActivity(i);
	}

	@Override
	public boolean onSwipeDown() {

		if (config.isVerticalSwipeEnabled()) {
			pageDown(Orientation.VERTICAL);
			return true;
		}

		return false;
	}

	@Override
	public boolean onSwipeUp() {

		if (config.isVerticalSwipeEnabled()) {
			pageUp(Orientation.VERTICAL);
			return true;
		}

		return false;
	}

	@Override
	public void onScreenTap() {

		FragmentActivity activity = getActivity();

		if (activity == null) {
			return;
		}

		stopAnimating();

		if (isToolbarShowed()) {
			hideToolbar();
		} else {
			showToolbar();
		}
		fontSettingView.setVisibility(View.GONE);
	}

	@Override
	public boolean onSwipeLeft() {

		if (config.isHorizontalSwipeEnabled()) {

			if (config.getReadingDirection() == ReadingDirection.LEFT_TO_RIGHT) {
				pageDown(Orientation.HORIZONTAL);
			} else {
				pageUp(Orientation.HORIZONTAL);
			}

			return true;
		}

		return false;
	}

	@Override
	public boolean onSwipeRight() {

		if (config.isHorizontalSwipeEnabled()) {

			if (config.getReadingDirection() == ReadingDirection.LEFT_TO_RIGHT) {
				pageUp(Orientation.HORIZONTAL);
			} else {
				pageDown(Orientation.HORIZONTAL);
			}

			return true;
		}

		return false;
	}

	@Override
	public boolean onTapLeftEdge() {
		if (config.isHorizontalTappingEnabled()) {
			if (config.getReadingDirection() == ReadingDirection.LEFT_TO_RIGHT) {
				pageUp(Orientation.HORIZONTAL);
			} else {
				pageDown(Orientation.HORIZONTAL);
			}

			return true;
		}

		return false;
	}

	@Override
	public boolean onTapRightEdge() {
		if (config.isHorizontalTappingEnabled()) {

			if (config.getReadingDirection() == ReadingDirection.LEFT_TO_RIGHT) {
				pageDown(Orientation.HORIZONTAL);
			} else {
				pageUp(Orientation.HORIZONTAL);
			}

			return true;
		}

		return false;
	}

	@Override
	public boolean onTapTopEdge() {
		if (config.isVerticalTappingEnabled()) {
			pageUp(Orientation.VERTICAL);
			return true;
		}

		return false;
	}

	@Override
	public boolean onTapBottomEdge() {
		if (config.isVerticalTappingEnabled()) {
			pageDown(Orientation.VERTICAL);
			return true;
		}

		return false;
	}

	@Override
	public boolean onLeftEdgeSlide(int value) {

		if (config.isBrightnessControlEnabled() && value != 0) {
			int baseBrightness = config.getBrightNess();

			int brightnessLevel = Math.min(99, value + baseBrightness);
			brightnessLevel = Math.max(1, brightnessLevel);

			final int level = brightnessLevel;

			String brightness = getString(R.string.brightness);
			setScreenBrightnessLevel(brightnessLevel);

			if (brightnessToast == null) {
				brightnessToast = Toast.makeText(context, brightness + ": " + brightnessLevel, Toast.LENGTH_SHORT);
			} else {
				brightnessToast.setText(brightness + ": " + brightnessLevel);
			}

			brightnessToast.show();

			backgroundHandler.post(new Runnable() {

				@Override
				public void run() {
					config.setBrightness(level);
				}
			});

			return true;
		}

		return false;
	}

	@Override
	public boolean onRightEdgeSlide(int value) {
		return false;
	}

	@Override
	public void onWordLongPressed(int startOffset, int endOffset, CharSequence word) {

		this.selectedWord = new BookView.SelectedWord(startOffset, endOffset, word);

		Activity activity = getActivity();

		if (activity != null) {
			activity.openContextMenu(bookView);
		}
	}

	public void launchFileManager() {
		Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
		intent.setType("file/*");

		intent.addCategory(Intent.CATEGORY_OPENABLE);

		try {
			startActivityForResult(intent, REQUEST_CODE_GET_CONTENT);
		} catch (ActivityNotFoundException e) {
			// No compatible file manager was found.
			Toast.makeText(context, getString(R.string.install_oi), Toast.LENGTH_SHORT).show();
		}
	}

	public boolean hasTableOfContents() {
		List<TocEntry> toc = this.bookView.getTableOfContents();
		return toc != null && !toc.isEmpty();
	}

	public List<NavigationCallback> getTableOfContents() {

		List<NavigationCallback> result = new ArrayList<NavigationCallback>();
		List<TocEntry> tocEntries = this.bookView.getTableOfContents();

		if (tocEntries != null) {

			for (final TocEntry tocEntry : tocEntries) {

				result.add(new NavigationCallback() {
					@Override
					public String getTitle() {
						return tocEntry.getTitle();
					}

					@Override
					public String getSubtitle() {
						return tocEntry.getHref();
					}

					@Override
					public void onClick() {
						bookView.navigateTo(tocEntry.getHref());
					}

					@Override
					public void onLongClick() {
						// Do nothing
					}
				});
			}

		}

		return result;
	}

	@Override
	public void onSaveInstanceState(final Bundle outState) {
		if (this.bookView != null) {
			outState.putInt(POS_KEY, this.bookView.getProgressPosition());
			outState.putInt(IDX_KEY, this.bookView.getIndex());
		}

	}

	public void performSearch(String query) {

		LOG.debug("Starting search for: " + query);

		final ProgressDialog searchProgress = new ProgressDialog(context);
		searchProgress.setOwnerActivity(getActivity());
		searchProgress.setCancelable(true);
		searchProgress.setMax(100);
		searchProgress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

		final SearchTextTask task = new SearchTextTask(bookView.getBook()) {

			int i = 0;

			@Override
			protected void onPreExecute() {
				super.onPreExecute();

				searchProgress.setMessage(getString(R.string.search_wait));
				searchProgress.show();

				// Hide on-screen keyboard if it is showing
				InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
				imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);

			}

			@Override
			protected void onProgressUpdate(SearchResult... values) {

				if (!isAdded()) {
					return;
				}

				super.onProgressUpdate(values);

				LOG.debug("Found match at index=" + values[0].getIndex() + ", offset=" + values[0].getStart()
						+ " with context " + values[0].getDisplay());
				SearchResult res = values[0];

				if (res.getDisplay() != null) {
					i++;
					String update = String.format(getString(R.string.search_hits), i);
					searchProgress.setMessage(update);
				}

				searchProgress.setProgress(bookView.getPercentageFor(res.getIndex(), res.getStart()));
			}

			@Override
			protected void onCancelled() {
				if (isAdded()) {
					Toast.makeText(context, R.string.search_cancelled, Toast.LENGTH_LONG).show();
				}
			}

			protected void onPostExecute(java.util.List<SearchResult> result) {

				searchProgress.dismiss();

				if (!isCancelled() && isAdded()) {
					if (result.size() > 0) {
						searchResults = result;
						showSearchResultDialog(result);
					} else {
						Toast.makeText(context, R.string.search_no_matches, Toast.LENGTH_LONG).show();
					}
				}
			};
		};

		searchProgress.setOnCancelListener(new DialogInterface.OnCancelListener() {

			@Override
			public void onCancel(DialogInterface dialog) {
				task.cancel(true);
			}
		});

		task.execute(query);
	}

	private void setSupportProgressBarIndeterminateVisibility(boolean enable) {
		FragmentActivity activity = getActivity();
		if (activity != null) {
			LOG.debug("Setting progress bar to " + enable);
			activity.setProgressBarIndeterminateVisibility(enable);
		} else {
			LOG.debug("Got null activity.");
		}
	}

	@Override
	public void onCalculatePageNumbersComplete() {
		setSupportProgressBarIndeterminateVisibility(false);
	}

	@Override
	public void onStartCalculatePageNumbers() {
		setSupportProgressBarIndeterminateVisibility(true);
	}

	public void onSearchRequested() {
		// 收起抽屉
		ReadingEpubActivity.instance.closeNavigationDrawer();

		if (this.searchMenuItem != null && searchMenuItem.getActionView() != null) {
			if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
				// getActivity().getActionBar().show();
			}
			this.searchMenuItem.expandActionView();
			this.searchMenuItem.getActionView().requestFocus();
		} else {
			dialogFactory.showSearchDialog(R.string.search_text, R.string.enter_query, this);
		}
	}

	// Hack to prevent showing the dialog twice
	private boolean isSearchResultsDialogShowing = false;

	private void showSearchResultDialog(final List<SearchResult> results) {

		if (isSearchResultsDialogShowing) {
			return;
		}

		isSearchResultsDialogShowing = true;

		AlertDialog.Builder builder = new AlertDialog.Builder(context);
		builder.setTitle(R.string.search_results);

		SearchResultAdapter adapter = new SearchResultAdapter(context, bookView, results);
		builder.setAdapter(adapter, adapter);

		AlertDialog dialog = builder.create();
		dialog.setOwnerActivity(getActivity());
		dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
			@Override
			public void onDismiss(DialogInterface dialogInterface) {
				isSearchResultsDialogShowing = false;
			}
		});
		dialog.show();
	}

	public boolean hasSearchResults() {
		return this.searchResults != null && !this.searchResults.isEmpty();
	}

	public List<NavigationCallback> getSearchResults() {

		List<NavigationCallback> result = new ArrayList<NavigationCallback>();

		if (searchResults == null) {
			return result;
		}

		final int totalNumberOfPages = bookView.getTotalNumberOfPages();

		int counter = 0;

		for (final SearchResult searchResult : this.searchResults) {

			int percentage = bookView.getPercentageFor(searchResult.getIndex(), searchResult.getStart());
			int pageNumber = bookView.getPageNumberFor(searchResult.getIndex(), searchResult.getStart());

			final String text;
			final int currentCount = counter;

			if (pageNumber != -1) {
				text = String.format(context.getString(R.string.page_number_of), pageNumber, totalNumberOfPages) + " ("
						+ percentage + "%)";
			} else {
				text = percentage + "%";
			}

			result.add(new NavigationCallback() {
				@Override
				public String getTitle() {
					return searchResult.getDisplay();
				}

				@Override
				public String getSubtitle() {
					return text;
				}

				@Override
				public void onClick() {
					bookView.navigateBySearchResult(searchResult);
				}

				@Override
				public void onLongClick() {
					// Do nothing
				}
			});

			counter++;
		}

		return result;
	}

	public boolean hasHighlights() {

		List<HighLight> highLights = this.highlightManager.getHighLights(bookView.getFileName());

		return highLights != null && !highLights.isEmpty();
	}

	public boolean hasBookmarks() {

		List<Bookmark> bookmarks = this.bookmarkDatabaseHelper.getBookmarksForFile(bookView.getFileName());

		return bookmarks != null && !bookmarks.isEmpty();
	}

	private String getHighlightLabel(int index, int position, String text) {

		final int totalNumberOfPages = bookView.getTotalNumberOfPages();

		int percentage = bookView.getPercentageFor(index, position);
		int pageNumber = bookView.getPageNumberFor(index, position);

		String result = percentage + "%";

		if (pageNumber != -1) {
			result = String.format(context.getString(R.string.page_number_of), pageNumber, totalNumberOfPages) + " ("
					+ percentage + "%)";
		}

		if (text != null && text.trim().length() > 0) {
			result += ": " + TextUtil.shortenText(text);
		}

		return result;
	}

	public List<NavigationCallback> getBookmarks() {

		List<Bookmark> bookmarks = this.bookmarkDatabaseHelper.getBookmarksForFile(bookView.getFileName());

		List<NavigationCallback> result = new ArrayList<NavigationCallback>();

		for (final Bookmark bookmark : bookmarks) {

			final String finalText = getHighlightLabel(bookmark.getIndex(), bookmark.getPosition(), null);

			result.add(new NavigationCallback() {
				@Override
				public String getTitle() {
					return bookmark.getName();
				}

				@Override
				public String getSubtitle() {
					return finalText;
				}

				@Override
				public void onClick() {
					bookView.navigateTo(bookmark.getIndex(), bookmark.getPosition());
				}

				@Override
				public void onLongClick() {
					onBookmarkClick(bookmark);
				}
			});

		}

		return result;
	}

	public List<NavigationCallback> getHighlights() {

		List<HighLight> highLights = this.highlightManager.getHighLights(bookView.getFileName());

		List<NavigationCallback> result = new ArrayList<NavigationCallback>();

		for (final HighLight highLight : highLights) {

			final String finalText = getHighlightLabel(highLight.getIndex(), highLight.getStart(),
					highLight.getTextNote());

			result.add(new NavigationCallback() {
				@Override
				public String getTitle() {
					return highLight.getDisplayText();
				}

				@Override
				public String getSubtitle() {
					return finalText;
				}

				@Override
				public void onClick() {
					bookView.navigateTo(highLight.getIndex(), highLight.getStart());
				}

				@Override
				public void onLongClick() {
					onHighLightClick(highLight);
				}
			});

		}

		return result;
	}

	@Override
	public void updateFontFamily(String fontName) {
		// 需要清空缓存过的章节ChapterSpan信息
		bookView.invalidateCachedText();
		updateFromPrefs();
	}

	@Override
	public void updateFontSize(int fontSize) {
		updateFromPrefs();
	}

	@Override
	public void updateParaHeight(int heightLevel) {
		updateFromPrefs();
	}

	@Override
	public void updateColorTheme(int theme) {

	}

	@Override
	public void onAudioPlayComplete() {
		layoutPlayAudio.setVisibility(View.GONE);
	}

	@Override
	public void onAudioPlayStart() {
		layoutPlayAudio.setVisibility(View.VISIBLE);

	}
	/** 第一次阅读，添加epub电子书到数据库 */
	private void importEpubFile(final String path) {
		Thread importThread = new Thread(new Runnable() {

			@Override
			public void run() {

				EpubReader epubReader = new EpubReader();
				Book book;
				try {
					book = epubReader.readEpubLazy(path, "UTF-8");

					bookItem = new BookInfoItem();
					bookItem.setAccount(Const.phone_number);

					Metadata metadata = book.getMetadata();
					// 作者
					String author = "";
					for (Author authorItem : metadata.getAuthors()) {
						author += authorItem.getFirstname() + " " + authorItem.getLastname() + ", ";
					}
					if(!TextUtils.isEmpty(author)){
						author = author.substring(0, author.length() - 2);
					}
					bookItem.setAuthor(author);
					bookItem.setBookId(bookId);
					bookItem.setBookPath(path);
					bookItem.setBookName(book.getTitle());
					bookItem.setIsTopMost(0);
					Date date = new Date();
					date.setYear(0);
					bookItem.setLastReadTime(date);
					bookItem.setLastChapterId("null");
					bookItem.setLastCharIndex(-1);
					bookItem.setReadPercent(-1f);

					// 保存图片
					bookItem.setCoverPath("null");
					Resource cover = book.getCoverImage();
					if (cover != null) {
						// 保存到文件
						String coverPath = EpubConst.EPUB_COVER_LOCAL_PATH + book.getTitle() + ".jpg";
						FileUtil.outPutToFile(cover.getData(), coverPath);
						bookItem.setCoverPath(coverPath);
					} else {
						//TODO 无法获取封面图片
					}

					// 插入到数据库中
					// 首先判断数据库中是否有该本书籍的信息
					BookInfoDbAdapter adapter = new BookInfoDbAdapter(activity,DBHelper.getInstance(activity));
					adapter.open();
					boolean isSuccess = false;
					if (!adapter.isStoreBookInfo(path,Const.phone_number)) {
						long id = adapter.insertTask(bookItem);
						isSuccess = id >= 0;
					}
					adapter.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});
		importThread.start();
	}
}
